import streamlit as st
import pandas as pd
import plotly.express as px
import plotly.graph_objects as go
from datetime import datetime, timedelta
import numpy as np
import os
import time
import logging
import sys
from io import StringIO

from api_client import StockApiClient
from portfolio_manager import PortfolioManager
from trading_strategy import TradingStrategy
from config import APP_TITLE, APP_DESCRIPTION, ALIYUN_APPCODE

# 页面配置
st.set_page_config(
    page_title="股票交易系统",
    page_icon="📈",
    layout="wide",
    initial_sidebar_state="expanded"
)

# 初始化API客户端
@st.cache_resource
def get_api_client():
    return StockApiClient(app_code=ALIYUN_APPCODE)

# 初始化持仓管理器
@st.cache_resource
def get_portfolio_manager():
    return PortfolioManager()

# 初始化交易策略
@st.cache_resource
def get_trading_strategy():
    return TradingStrategy()

# 设置日志捕获器
class StreamlitLogHandler(logging.Handler):
    def __init__(self, placeholder):
        super().__init__()
        self.placeholder = placeholder
        self.logs = []
        self.formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    
    def emit(self, record):
        log_entry = self.formatter.format(record)
        self.logs.append(log_entry)
        # 只显示最新的50条日志
        log_text = "\n".join(self.logs[-50:])
        self.placeholder.text_area("API 调用日志", log_text, height=300)

def main():
    # 页面标题
    st.title("股票交易系统")
    st.caption("整合价值投资分析、大跌股票分析、持仓管理和交易策略")
    
    # 侧边栏 - 功能选择
    st.sidebar.header("功能选择")
    app_mode = st.sidebar.selectbox(
        "选择功能模式",
        ["持仓管理", "价值投资分析", "大跌股票分析", "市场概览", "交易策略分析"]
    )
    
    # 根据选择的功能显示不同的内容
    if app_mode == "持仓管理":
        portfolio_management_app()
    elif app_mode == "价值投资分析":
        value_investment_app()
    elif app_mode == "大跌股票分析":
        price_drop_app()
    elif app_mode == "交易策略分析":
        trading_strategy_app()
    else:
        market_overview_app()

def portfolio_management_app():
    """持仓管理功能"""
    st.header("持仓管理")
    
    # 初始化持仓管理器和API客户端
    portfolio_manager = get_portfolio_manager()
    api_client = get_api_client()
    
    # 创建标签页
    tabs = st.tabs(["持仓概览", "添加持仓", "交易记录", "止盈止损提醒"])
    
    with tabs[0]:
        st.subheader("持仓概览")
        
        # 获取持仓数据
        holdings = portfolio_manager.get_holdings()
        
        if not holdings.empty:
            # 获取最新报价
            symbols = holdings["symbol"].tolist()
            quotes = api_client.get_stock_quotes(symbols)
            
            if not quotes.empty:
                # 更新持仓的当前价格
                for _, quote in quotes.iterrows():
                    symbol = quote["symbol"]
                    price = float(quote["price"])
                    portfolio_manager.update_position(symbol, current_price=price)
                
                # 重新获取更新后的持仓
                holdings = portfolio_manager.get_holdings()
                
                # 计算投资组合统计信息
                stats = portfolio_manager.calculate_portfolio_stats()
                
                # 显示统计信息
                col1, col2, col3, col4 = st.columns(4)
                col1.metric("持仓总成本", f"¥{stats['total_cost']:,.2f}")
                col2.metric("持仓总市值", f"¥{stats['total_market_value']:,.2f}")
                col3.metric("总盈亏", f"¥{stats['total_profit_loss']:,.2f}", 
                           f"{stats['total_profit_loss_percent']:.2f}%")
                col4.metric("持仓数量", stats['position_count'])
                
                # 显示持仓表格
                st.dataframe(holdings[[
                    "symbol", "name", "buy_price", "current_price", 
                    "shares", "market_value", "profit_loss", "profit_loss_percent",
                    "buy_date", "strategy", "stop_loss", "take_profit"
                ]].rename(columns={
                    "symbol": "代码", 
                    "name": "名称", 
                    "buy_price": "买入价", 
                    "current_price": "当前价", 
                    "shares": "持仓数量", 
                    "market_value": "市值", 
                    "profit_loss": "盈亏", 
                    "profit_loss_percent": "盈亏率(%)", 
                    "buy_date": "买入日期", 
                    "strategy": "策略", 
                    "stop_loss": "止损价", 
                    "take_profit": "止盈价"
                }))
                
                # 创建持仓饼图
                if len(holdings) > 1:
                    fig = px.pie(
                        holdings, 
                        values="market_value", 
                        names="name", 
                        title="持仓分布",
                        hover_data=["profit_loss_percent"]
                    )
                    st.plotly_chart(fig)
                
                # 平仓功能
                st.subheader("平仓操作")
                col1, col2 = st.columns(2)
                with col1:
                    close_symbol = st.selectbox(
                        "选择要平仓的股票", 
                        options=holdings["symbol"].tolist(),
                        format_func=lambda x: f"{x} - {holdings[holdings['symbol'] == x]['name'].values[0]}"
                    )
                
                with col2:
                    close_price = st.number_input(
                        "平仓价格", 
                        min_value=0.01, 
                        value=float(holdings[holdings["symbol"] == close_symbol]["current_price"].values[0]),
                        step=0.01
                    )
                
                close_notes = st.text_area("平仓备注", value="", max_chars=200)
                
                if st.button("确认平仓"):
                    result = portfolio_manager.close_position(
                        close_symbol, 
                        close_price, 
                        notes=close_notes
                    )
                    if result:
                        st.success(f"成功平仓 {close_symbol}")
                        st.experimental_rerun()
                    else:
                        st.error("平仓失败")
            else:
                st.warning("获取股票报价失败")
        else:
            st.info("暂无持仓数据")
            
            # 添加示例数据按钮
            if st.button("添加示例持仓数据"):
                # 添加示例持仓
                portfolio_manager.add_position(
                    "sh600036", "招商银行", 43.0, 2300, 
                    date="2023-05-15", strategy="稳健型",
                    stop_loss=39.56, take_profit=49.45, 
                    notes="股价跌4%，接近20日均线"
                )
                
                portfolio_manager.add_position(
                    "sh600028", "中国石化", 5.0, 20000, 
                    date="2023-05-20", strategy="稳健型",
                    stop_loss=4.6, take_profit=5.75, 
                    notes="股价跌5%，接近20日均线"
                )
                
                st.success("已添加示例持仓数据")
                st.experimental_rerun()
    
    with tabs[1]:
        st.subheader("添加新持仓")
        
        col1, col2 = st.columns(2)
        
        with col1:
            symbol = st.text_input("股票代码（如sh600036）", value="")
            name = st.text_input("股票名称", value="")
            price = st.number_input("买入价格", min_value=0.01, value=10.0, step=0.01)
            shares = st.number_input("买入数量", min_value=100, value=1000, step=100)
        
        with col2:
            buy_date = st.date_input("买入日期", value=datetime.now())
            strategy = st.selectbox("投资策略", options=["稳健型", "高收益型", "价值投资", "其他"])
            stop_loss = st.number_input("止损价格", min_value=0.0, value=0.0, step=0.01)
            take_profit = st.number_input("止盈价格", min_value=0.0, value=0.0, step=0.01)
        
        notes = st.text_area("交易备注", value="", max_chars=200)
        
        if st.button("添加持仓"):
            if not symbol or not name:
                st.error("股票代码和名称不能为空")
            else:
                result = portfolio_manager.add_position(
                    symbol, name, price, shares, 
                    date=buy_date.strftime("%Y-%m-%d"), 
                    strategy=strategy,
                    stop_loss=stop_loss if stop_loss > 0 else None, 
                    take_profit=take_profit if take_profit > 0 else None, 
                    notes=notes
                )
                if result:
                    st.success(f"成功添加 {symbol}({name}) 的持仓")
                    st.experimental_rerun()
                else:
                    st.error("添加持仓失败")
    
    with tabs[2]:
        st.subheader("交易记录")
        
        # 获取交易记录
        transactions = portfolio_manager.get_transactions()
        
        if not transactions.empty:
            # 显示交易记录
            # 确保选择存在的列
            display_columns = []
            rename_dict = {}
            
            for col, new_name in [
                ("date", "日期"), 
                ("symbol", "代码"), 
                ("name", "名称"), 
                ("type", "类型"), 
                ("price", "价格"), 
                ("shares", "数量"), 
                ("amount", "金额")
            ]:
                if col in transactions.columns:
                    display_columns.append(col)
                    rename_dict[col] = new_name
            
            # 只有卖出交易才有盈亏信息
            if "profit_loss" in transactions.columns:
                display_columns.append("profit_loss")
                rename_dict["profit_loss"] = "盈亏"
            
            if "profit_loss_percent" in transactions.columns:
                display_columns.append("profit_loss_percent")
                rename_dict["profit_loss_percent"] = "盈亏率(%)"
                
            if "strategy" in transactions.columns:
                display_columns.append("strategy")
                rename_dict["strategy"] = "策略"
                
            st.dataframe(transactions[display_columns].rename(columns=rename_dict))
            
            # 计算交易统计
            buy_transactions = transactions[transactions["type"] == "买入"]
            sell_transactions = transactions[transactions["type"] == "卖出"]
            
            if not sell_transactions.empty:
                total_profit = sell_transactions["profit_loss"].sum()
                avg_profit_percent = sell_transactions["profit_loss_percent"].mean()
                
                col1, col2, col3 = st.columns(3)
                col1.metric("总交易次数", len(transactions))
                col2.metric("总盈亏", f"¥{total_profit:,.2f}")
                col3.metric("平均盈亏率", f"{avg_profit_percent:.2f}%")
        else:
            st.info("暂无交易记录")
    
    with tabs[3]:
        st.subheader("止盈止损提醒")
        
        # 获取持仓数据
        holdings = portfolio_manager.get_holdings()
        
        if not holdings.empty:
            # 获取最新报价
            symbols = holdings["symbol"].tolist()
            quotes = api_client.get_stock_quotes(symbols)
            
            if not quotes.empty:
                # 计算止盈止损提醒
                alerts = portfolio_manager.calculate_alerts(quotes)
                
                if alerts:
                    for alert in alerts:
                        alert_type = alert["type"]
                        color = "red" if alert_type == "止损" else "green"
                        
                        st.markdown(f"""
                        <div style="padding: 10px; border-left: 5px solid {color}; background-color: rgba(0,0,0,0.05);">
                            <h4 style="color: {color};">{alert_type}提醒: {alert['symbol']} - {alert['name']}</h4>
                            <p>当前价格: {alert['current_price']:.2f} | {alert_type}价格: {alert['threshold_price']:.2f}</p>
                            <p>买入价格: {alert['buy_price']:.2f} | 盈亏比例: {alert['profit_loss_percent']:.2f}%</p>
                        </div>
                        """, unsafe_allow_html=True)
                else:
                    st.info("暂无止盈止损提醒")
            else:
                st.warning("获取股票报价失败")
        else:
            st.info("暂无持仓数据")

def value_investment_app():
    """格雷厄姆价值投资分析功能"""
    st.header("格雷厄姆价值投资分析")
    st.markdown("基于格雷厄姆价值投资理念，筛选A股市场中被低估且有低吸机会的股票")
    
    # 参数设置
    with st.expander("参数设置", expanded=True):
        col1, col2 = st.columns(2)
        
        with col1:
            # 成交额排名
            limit = st.slider(
                "获取股票数量", 
                min_value=50, 
                max_value=500, 
                value=100,
                step=50,
                key="vi_limit"
            )
            
            # 价值股筛选参数
            st.subheader("价值股筛选标准")
            
            pe_threshold = st.slider(
                "市盈率(PE)上限", 
                min_value=5, 
                max_value=30, 
                value=15,
                step=1,
                key="vi_pe"
            )
            
            pb_threshold = st.slider(
                "市净率(PB)上限", 
                min_value=0.5, 
                max_value=3.0, 
                value=1.5,
                step=0.1,
                key="vi_pb"
            )
        
        with col2:
            div_yield_threshold = st.slider(
                "股息率(%)下限", 
                min_value=1.0, 
                max_value=10.0, 
                value=4.0,
                step=0.5,
                key="vi_div"
            )
            
            market_cap_threshold = st.slider(
                "市值下限(亿元)", 
                min_value=10, 
                max_value=500, 
                value=100,
                step=10,
                key="vi_cap"
            )
            
            # 低吸参数
            st.subheader("低吸策略参数")
            
            drop_min = st.slider(
                "最小跌幅(%)", 
                min_value=1.0, 
                max_value=5.0, 
                value=2.0,
                step=0.5,
                key="vi_drop_min"
            )
            
            drop_max = st.slider(
                "最大跌幅(%)", 
                min_value=3.0, 
                max_value=10.0, 
                value=6.0,
                step=0.5,
                key="vi_drop_max"
            )
    
    # 添加到持仓选项
    add_to_portfolio = st.checkbox("将筛选结果添加到持仓", value=False)
    
    # 获取数据按钮
    if st.button("分析价值股", key="btn_value_stocks"):
        with st.spinner("正在获取和分析股票数据..."):
            try:
                # 创建进度条
                progress_bar = st.progress(0)
                status_text = st.empty()
                
                # 更新状态
                status_text.text("正在初始化API客户端...")
                progress_bar.progress(10)
                
                api_client = get_api_client()
                
                # 更新状态
                status_text.text("正在获取股票数据...")
                progress_bar.progress(30)
                
                # 创建日志容器
                log_tabs = st.tabs(["分析结果", "处理日志"])
                
                with log_tabs[1]:
                    col1, col2 = st.columns([1, 1])
                    
                    with col1:
                        console_log = st.empty()
                    
                    with col2:
                        api_log = st.empty()
                
                # 设置日志处理器
                log_handler = StreamlitLogHandler(api_log)
                root_logger = logging.getLogger()
                root_logger.addHandler(log_handler)
                
                # 使用StringIO捕获控制台输出
                old_stdout = sys.stdout
                sys.stdout = mystdout = StringIO()
                
                # 获取价值股
                data, error = api_client.get_value_stocks(
                    pe_threshold=pe_threshold,
                    pb_threshold=pb_threshold,
                    div_yield_threshold=div_yield_threshold,
                    market_cap_threshold=market_cap_threshold,
                    drop_min=drop_min,
                    drop_max=drop_max,
                    limit=limit
                )
                
                # 恢复标准输出
                sys.stdout = old_stdout
                
                # 显示控制台输出
                console_output = mystdout.getvalue()
                console_log.text_area("处理日志", console_output, height=300)
                
                # 更新状态
                status_text.text("分析完成")
                progress_bar.progress(100)
                
                # 显示结果
                with log_tabs[0]:
                    if error:
                        st.error(error)
                    elif data.empty:
                        st.warning("未找到符合条件的价值股")
                    else:
                        st.success(f"找到 {len(data)} 只符合条件的价值股")
                        
                        # 显示数据表格
                        st.dataframe(data)
                        
                        # 创建可视化图表
                        create_value_stock_visualizations(data)
                        
                        # 显示投资建议
                        show_investment_advice(data, drop_max)
                        
                        # 添加到持仓功能
                        if add_to_portfolio:
                            st.subheader("添加到持仓")
                            
                            # 获取持仓管理器
                            portfolio_manager = get_portfolio_manager()
                            
                            # 选择要添加的股票
                            selected_stock = st.selectbox(
                                "选择要添加到持仓的股票",
                                options=data["代码"].tolist(),
                                format_func=lambda x: f"{x} - {data[data['代码'] == x]['名称'].values[0]}"
                            )
                            
                            if selected_stock:
                                stock_data = data[data["代码"] == selected_stock].iloc[0]
                                
                                col1, col2 = st.columns(2)
                                
                                with col1:
                                    shares = st.number_input(
                                        "买入数量", 
                                        min_value=100, 
                                        value=1000, 
                                        step=100
                                    )
                                
                                with col2:
                                    strategy = st.selectbox(
                                        "投资策略",
                                        options=["稳健型", "高收益型", "价值投资"]
                                    )
                                
                                notes = st.text_area(
                                    "交易备注", 
                                    value=f"格雷厄姆价值投资策略，PE={stock_data['市盈率']:.2f}, PB={stock_data['市净率']:.2f}, 跌幅={stock_data['涨跌幅']:.2f}%", 
                                    max_chars=200
                                )
                                
                                # 计算止损止盈价格
                                price = stock_data["最新价"]
                                stop_loss = price * 0.92  # 跌8%
                                take_profit = price * 1.15  # 涨15%
                                
                                if st.button("确认添加到持仓"):
                                    result = portfolio_manager.add_position(
                                        selected_stock, 
                                        stock_data["名称"], 
                                        price, 
                                        shares, 
                                        strategy=strategy,
                                        stop_loss=stop_loss, 
                                        take_profit=take_profit, 
                                        notes=notes
                                    )
                                    
                                    if result:
                                        st.success(f"成功添加 {selected_stock}({stock_data['名称']}) 到持仓")
                                    else:
                                        st.error("添加持仓失败")
                
                # 移除日志处理器
                root_logger.removeHandler(log_handler)
                
            except Exception as e:
                st.error(f"分析过程中出错: {str(e)}")

def price_drop_app():
    """大跌股票分析功能"""
    st.header("大跌股票分析")
    st.markdown("分析市场中大幅下跌的股票，寻找低吸机会")
    
    # 参数设置
    with st.expander("参数设置", expanded=True):
        col1, col2 = st.columns(2)
        
        with col1:
            # 成交额排名
            limit = st.slider(
                "获取股票数量", 
                min_value=50, 
                max_value=500, 
                value=100,
                step=50,
                key="pd_limit"
            )
            
            # 大跌筛选参数
            drop_min = st.slider(
                "最小跌幅(%)", 
                min_value=2.0, 
                max_value=10.0, 
                value=5.0,
                step=0.5,
                key="pd_drop_min"
            )
            
            volume_ratio_min = st.slider(
                "成交量比下限", 
                min_value=0.5, 
                max_value=5.0, 
                value=1.0,
                step=0.1,
                key="pd_vol_min"
            )
        
        with col2:
            # 交易策略选择
            strategy_type = st.radio(
                "交易策略",
                options=["稳健型", "高收益型"],
                key="pd_strategy"
            )
            
            # 市值范围
            market_cap_min = st.slider(
                "市值下限(亿元)", 
                min_value=10, 
                max_value=500, 
                value=50,
                step=10,
                key="pd_cap_min"
            )
            
            # 是否排除ST股票
            exclude_st = st.checkbox("排除ST股票", value=True, key="pd_exclude_st")
    
    # 添加到持仓选项
    add_to_portfolio = st.checkbox("将筛选结果添加到持仓", value=False, key="pd_add_portfolio")
    
    # 获取数据按钮
    if st.button("分析大跌股票", key="btn_price_drop"):
        with st.spinner("正在获取和分析股票数据..."):
            try:
                # 创建进度条
                progress_bar = st.progress(0)
                status_text = st.empty()
                
                # 更新状态
                status_text.text("正在初始化API客户端...")
                progress_bar.progress(10)
                
                api_client = get_api_client()
                trading_strategy = get_trading_strategy()
                
                # 更新状态
                status_text.text("正在获取股票排行数据...")
                progress_bar.progress(20)
                
                # 创建日志容器
                log_tabs = st.tabs(["分析结果", "处理日志"])
                
                with log_tabs[1]:
                    col1, col2 = st.columns([1, 1])
                    
                    with col1:
                        console_log = st.empty()
                    
                    with col2:
                        api_log = st.empty()
                
                # 设置日志处理器
                log_handler = StreamlitLogHandler(api_log)
                root_logger = logging.getLogger()
                root_logger.addHandler(log_handler)
                
                # 使用StringIO捕获控制台输出
                old_stdout = sys.stdout
                sys.stdout = mystdout = StringIO()
                
                # 获取股票排行（按成交额排序）
                stocks = api_client.get_stock_rank(sort_field="value", ascending=False, limit=limit)
                
                if stocks.empty:
                    error_msg = "无法获取股票排行数据"
                    console_log.text_area("处理日志", error_msg, height=300)
                    with log_tabs[0]:
                        st.error(error_msg)
                    return
                
                # 更新状态
                status_text.text(f"正在分析{len(stocks)}只股票的大跌情况...")
                progress_bar.progress(40)
                
                # 筛选大跌股票
                drop_stocks = []
                
                # 批量处理，每批10个股票
                batch_size = 10
                total_batches = (len(stocks) + batch_size - 1) // batch_size
                
                for batch_idx in range(total_batches):
                    start_idx = batch_idx * batch_size
                    end_idx = min((batch_idx + 1) * batch_size, len(stocks))
                    batch_stocks = stocks.iloc[start_idx:end_idx]
                    
                    batch_progress = 40 + (batch_idx / total_batches) * 50
                    progress_bar.progress(int(batch_progress))
                    status_text.text(f"正在处理第{batch_idx+1}/{total_batches}批股票...")
                    
                    for _, stock in batch_stocks.iterrows():
                        symbol = stock["symbol"]
                        name = stock["name"]
                        
                        # 排除ST股票
                        if exclude_st and ("ST" in name or "st" in name or "*" in name):
                            continue
                        
                        # 检查跌幅
                        change_rate = float(stock["changeRate"])
                        if change_rate >= -drop_min:
                            continue
                        
                        # 获取股票详情和K线数据
                        basic_info, kline_data, error = api_client.get_stock_detail(symbol)
                        
                        if error or kline_data.empty:
                            continue
                        
                        # 计算技术指标
                        kline_data = trading_strategy.calculate_technical_indicators(kline_data)
                        
                        # 检查市值
                        market_cap = basic_info.get("总市值(亿)", 0)
                        if market_cap < market_cap_min:
                            continue
                        
                        # 检查成交量
                        if "成交量比" in kline_data.columns and not kline_data.empty:
                            volume_ratio = kline_data.iloc[-1]["成交量比"]
                            if volume_ratio < volume_ratio_min:
                                continue
                        
                        # 根据策略类型检查买入信号
                        current_price = float(stock["price"])
                        
                        if strategy_type == "稳健型":
                            signal, reason = trading_strategy.stable_strategy_buy_signal(kline_data, current_price)
                            signal_type = "稳健型"
                        else:
                            signal, reason, signal_type = trading_strategy.high_return_strategy_buy_signal(kline_data, current_price)
                        
                        if signal:
                            # 计算止损止盈价格
                            stop_loss = trading_strategy.calculate_stop_loss(strategy_type, current_price, kline_data)
                            take_profit = trading_strategy.calculate_take_profit(strategy_type, current_price, signal_type=signal_type)
                            
                            # 添加到大跌股票列表
                            drop_stock = {
                                "代码": symbol,
                                "名称": name,
                                "最新价": current_price,
                                "涨跌幅": change_rate,
                                "成交量比": volume_ratio if "成交量比" in kline_data.columns and not kline_data.empty else 0,
                                "市盈率": basic_info.get("市盈率(TTM)", 0),
                                "市净率": basic_info.get("市净率", 0),
                                "总市值(亿)": market_cap,
                                "信号类型": signal_type,
                                "买入理由": reason,
                                "止损价": stop_loss,
                                "止盈价": take_profit
                            }
                            drop_stocks.append(drop_stock)
                
                # 恢复标准输出
                sys.stdout = old_stdout
                
                # 显示控制台输出
                console_output = mystdout.getvalue()
                console_log.text_area("处理日志", console_output, height=300)
                
                # 更新状态
                status_text.text("分析完成")
                progress_bar.progress(100)
                
                # 显示结果
                with log_tabs[0]:
                    if not drop_stocks:
                        st.warning("未找到符合条件的大跌股票")
                    else:
                        # 转换为DataFrame
                        data = pd.DataFrame(drop_stocks)
                        
                        st.success(f"找到 {len(data)} 只符合条件的大跌股票")
                        
                        # 显示数据表格
                        st.dataframe(data)
                        
                        # 创建可视化图表
                        create_price_drop_visualizations(data)
                        
                        # 添加到持仓功能
                        if add_to_portfolio:
                            st.subheader("添加到持仓")
                            
                            # 获取持仓管理器
                            portfolio_manager = get_portfolio_manager()
                            
                            # 选择要添加的股票
                            selected_stock = st.selectbox(
                                "选择要添加到持仓的股票",
                                options=data["代码"].tolist(),
                                format_func=lambda x: f"{x} - {data[data['代码'] == x]['名称'].values[0]}"
                            )
                            
                            if selected_stock:
                                stock_data = data[data["代码"] == selected_stock].iloc[0]
                                
                                col1, col2 = st.columns(2)
                                
                                with col1:
                                    shares = st.number_input(
                                        "买入数量", 
                                        min_value=100, 
                                        value=1000, 
                                        step=100,
                                        key="pd_shares"
                                    )
                                
                                with col2:
                                    strategy = st.selectbox(
                                        "投资策略",
                                        options=["稳健型", "高收益型"],
                                        index=0 if stock_data["信号类型"] == "稳健型" else 1,
                                        key="pd_strategy_select"
                                    )
                                
                                notes = st.text_area(
                                    "交易备注", 
                                    value=f"{stock_data['信号类型']}策略，跌幅{stock_data['涨跌幅']:.2f}%，{stock_data['买入理由']}", 
                                    max_chars=200,
                                    key="pd_notes"
                                )
                                
                                if st.button("确认添加到持仓", key="pd_add_btn"):
                                    result = portfolio_manager.add_position(
                                        selected_stock, 
                                        stock_data["名称"], 
                                        stock_data["最新价"], 
                                        shares, 
                                        strategy=strategy,
                                        stop_loss=stock_data["止损价"], 
                                        take_profit=stock_data["止盈价"], 
                                        notes=notes
                                    )
                                    
                                    if result:
                                        st.success(f"成功添加 {selected_stock}({stock_data['名称']}) 到持仓")
                                    else:
                                        st.error("添加持仓失败")
                
                # 移除日志处理器
                root_logger.removeHandler(log_handler)
                
            except Exception as e:
                st.error(f"分析过程中出错: {str(e)}")

def trading_strategy_app():
    """交易策略分析功能"""
    st.header("交易策略分析")
    st.markdown("基于稳健型和高收益型交易策略分析个股买入时机和止盈止损点")
    
    # 股票代码输入
    col1, col2 = st.columns(2)
    
    with col1:
        symbol = st.text_input("输入股票代码（如sh600036）", value="")
    
    with col2:
        strategy_type = st.radio(
            "选择交易策略",
            options=["稳健型", "高收益型"]
        )
    
    # 分析按钮
    if st.button("分析交易策略") and symbol:
        with st.spinner(f"正在分析 {symbol} 的交易策略..."):
            try:
                # 初始化API客户端和交易策略
                api_client = get_api_client()
                trading_strategy = get_trading_strategy()
                
                # 获取股票详情和K线数据
                basic_info, kline_data, error = api_client.get_stock_detail(symbol)
                
                if error:
                    st.error(f"获取股票数据失败: {error}")
                    return
                
                if kline_data.empty:
                    st.warning("未获取到K线数据")
                    return
                
                # 计算技术指标
                kline_data = trading_strategy.calculate_technical_indicators(kline_data)
                
                # 获取最新报价
                quotes = api_client.get_stock_quotes([symbol])
                if quotes.empty:
                    st.warning("获取最新报价失败")
                    return
                
                current_price = float(quotes.iloc[0]["price"])
                
                # 显示基本信息
                st.subheader(f"{symbol} - {basic_info.get('股票名称', '')}")
                
                col1, col2, col3, col4 = st.columns(4)
                col1.metric("最新价", f"{current_price:.2f}")
                col2.metric("涨跌幅", f"{basic_info.get('涨跌幅', 0):.2f}%")
                col3.metric("市盈率", f"{basic_info.get('市盈率(TTM)', 0):.2f}")
                col4.metric("市净率", f"{basic_info.get('市净率', 0):.2f}")
                
                # 创建K线图
                st.subheader("K线图与均线")
                
                fig = go.Figure()
                
                # 添加K线
                fig.add_trace(go.Candlestick(
                    x=kline_data['日期'],
                    open=kline_data['开盘价'],
                    high=kline_data['最高价'],
                    low=kline_data['最低价'],
                    close=kline_data['收盘价'],
                    name='K线'
                ))
                
                # 添加均线
                if 'MA5' in kline_data.columns:
                    fig.add_trace(go.Scatter(
                        x=kline_data['日期'],
                        y=kline_data['MA5'],
                        mode='lines',
                        name='MA5',
                        line=dict(color='blue', width=1)
                    ))
                
                if 'MA10' in kline_data.columns:
                    fig.add_trace(go.Scatter(
                        x=kline_data['日期'],
                        y=kline_data['MA10'],
                        mode='lines',
                        name='MA10',
                        line=dict(color='orange', width=1)
                    ))
                
                if 'MA20' in kline_data.columns:
                    fig.add_trace(go.Scatter(
                        x=kline_data['日期'],
                        y=kline_data['MA20'],
                        mode='lines',
                        name='MA20',
                        line=dict(color='green', width=1)
                    ))
                
                if 'MA60' in kline_data.columns:
                    fig.add_trace(go.Scatter(
                        x=kline_data['日期'],
                        y=kline_data['MA60'],
                        mode='lines',
                        name='MA60',
                        line=dict(color='red', width=1)
                    ))
                
                # 更新布局
                fig.update_layout(
                    title=f"{symbol} K线图",
                    xaxis_title="日期",
                    yaxis_title="价格",
                    xaxis_rangeslider_visible=False
                )
                
                st.plotly_chart(fig, use_container_width=True)
                
                # 分析交易信号
                if strategy_type == "稳健型":
                    signal, reason = trading_strategy.stable_strategy_buy_signal(kline_data, current_price)
                    signal_type = "稳健型"
                else:
                    signal, reason, signal_type = trading_strategy.high_return_strategy_buy_signal(kline_data, current_price)
                    if signal_type is None:
                        signal_type = "高收益型"
                
                # 计算止损止盈价格
                stop_loss = trading_strategy.calculate_stop_loss(strategy_type, current_price, kline_data)
                take_profit = trading_strategy.calculate_take_profit(strategy_type, current_price, signal_type=signal_type)
                
                # 显示交易建议
                st.subheader("交易策略分析")
                
                if signal:
                    st.success(f"**买入信号**: {reason}")
                    
                    col1, col2, col3 = st.columns(3)
                    col1.metric("建议买入价", f"{current_price:.2f}")
                    col2.metric("止损价", f"{stop_loss:.2f}", f"{(stop_loss - current_price) / current_price * 100:.2f}%")
                    col3.metric("止盈价", f"{take_profit:.2f}", f"{(take_profit - current_price) / current_price * 100:.2f}%")
                    
                    # 添加到持仓功能
                    st.subheader("添加到持仓")
                    
                    portfolio_manager = get_portfolio_manager()
                    
                    col1, col2 = st.columns(2)
                    
                    with col1:
                        shares = st.number_input("买入数量", min_value=100, value=1000, step=100)
                    
                    with col2:
                        notes = st.text_area("交易备注", value=f"{strategy_type}策略，{reason}", max_chars=200)
                    
                    if st.button("确认添加到持仓"):
                        result = portfolio_manager.add_position(
                            symbol, 
                            basic_info.get('股票名称', symbol), 
                            current_price, 
                            shares, 
                            strategy=strategy_type,
                            stop_loss=stop_loss, 
                            take_profit=take_profit, 
                            notes=notes
                        )
                        
                        if result:
                            st.success(f"成功添加 {symbol} 到持仓")
                        else:
                            st.error("添加持仓失败")
                else:
                    st.warning(f"**无买入信号**: {reason}")
                    
                    # 显示策略参数
                    st.subheader("策略参数参考")
                    
                    if strategy_type == "稳健型":
                        st.markdown("""
                        **稳健型策略参数**:
                        - 买入时机: 股价跌5%-10%到20日均线附近（±5%），成交量缩（回调确认）
                        - 止损价格: 跌8%或跌破60日均线（取较严者）
                        - 止盈价格: 涨15%-20%或接近内在价值
                        """)
                    else:
                        st.markdown("""
                        **高收益型策略参数**:
                        - 买入时机(低吸): 开盘跌2%-6%，量缩（恐慌抛售）或放量（资金抢筹）
                        - 买入时机(突破): 突破20日/52周高点后回踩5%，量增2倍
                        - 止损价格: 跌8%或跌破5日均线（短线用）
                        - 止盈价格: 涨10%-20%（低吸10%，突破20%）
                        """)
            
            except Exception as e:
                st.error(f"分析过程中出错: {str(e)}")

def market_overview_app():
    """市场概览功能"""
    st.header("市场概览")
    st.markdown("提供A股市场整体情况，包括指数行情、涨跌分布和板块热度")
    
    # 初始化API客户端
    api_client = get_api_client()
    
    # 获取指数行情
    indices = ["sh000001", "sz399001", "sz399006"]
    index_names = {"sh000001": "上证指数", "sz399001": "深证成指", "sz399006": "创业板指"}
    
    with st.spinner("正在获取指数行情..."):
        quotes = api_client.get_stock_quotes(indices)
        
        if not quotes.empty:
            # 显示指数行情
            st.subheader("大盘指数")
            
            cols = st.columns(len(indices))
            for i, symbol in enumerate(indices):
                quote_data = quotes[quotes["symbol"] == symbol]
                if not quote_data.empty:
                    price = float(quote_data["price"].values[0])
                    change_rate = float(quote_data["changeRate"].values[0])
                    color = "green" if change_rate >= 0 else "red"
                    
                    cols[i].metric(
                        index_names[symbol], 
                        f"{price:.2f}", 
                        f"{change_rate:.2f}%",
                        delta_color="normal" if change_rate >= 0 else "inverse"
                    )
        else:
            st.warning("获取指数行情失败")
    
    # 创建标签页
    tabs = st.tabs(["市场热度", "行业板块", "涨跌分布"])
    
    with tabs[0]:
        st.subheader("市场热度")
        
        # 获取成交额前20的股票
        with st.spinner("正在获取市场热度数据..."):
            hot_stocks = api_client.get_stock_rank(sort_field="value", ascending=False, limit=20)
            
            if not hot_stocks.empty:
                # 转换为DataFrame
                hot_data = []
                for _, stock in hot_stocks.iterrows():
                    hot_data.append({
                        "代码": stock["symbol"],
                        "名称": stock["name"],
                        "最新价": float(stock["price"]),
                        "涨跌幅": float(stock["changeRate"]),
                        "成交量": float(stock["volume"]),
                        "成交额": float(stock["value"]) / 10000  # 转换为万元
                    })
                
                hot_df = pd.DataFrame(hot_data)
                
                # 显示表格
                st.dataframe(hot_df)
                
                # 创建成交额热力图
                fig = px.treemap(
                    hot_df,
                    path=["名称"],
                    values="成交额",
                    color="涨跌幅",
                    color_continuous_scale="RdYlGn",
                    range_color=[-10, 10],
                    title="市场成交额热力图（万元）"
                )
                st.plotly_chart(fig, use_container_width=True)
            else:
                st.warning("获取市场热度数据失败")
    
    with tabs[1]:
        st.subheader("行业板块")
        
        # 这里可以添加行业板块分析，但需要相应的API支持
        st.info("行业板块分析功能正在开发中...")
    
    with tabs[2]:
        st.subheader("涨跌分布")
        
        # 获取涨跌分布数据
        with st.spinner("正在获取涨跌分布数据..."):
            # 这里需要相应的API支持，暂时使用模拟数据
            distribution_data = {
                "涨停": 35,
                "5%以上": 126,
                "0-5%": 1024,
                "平盘": 89,
                "0-5%下跌": 1245,
                "5%以上下跌": 156,
                "跌停": 42
            }
            
            # 创建涨跌分布图
            distribution_df = pd.DataFrame({
                "区间": list(distribution_data.keys()),
                "数量": list(distribution_data.values())
            })
            
            # 设置颜色
            colors = ["#d81e06", "#f4511e", "#fb8c00", "#ffb300", "#00c853", "#2196f3", "#0d47a1"]
            
            fig = px.bar(
                distribution_df,
                x="区间",
                y="数量",
                title="A股涨跌分布",
                color="区间",
                color_discrete_sequence=colors
            )
            st.plotly_chart(fig, use_container_width=True)

def create_value_stock_visualizations(data):
    """创建价值股数据可视化图表"""
    if data.empty:
        return
    
    st.subheader("数据可视化")
    
    # 创建标签页
    viz_tabs = st.tabs(["市盈率分布", "市净率分布", "市值分布", "跌幅分布"])
    
    with viz_tabs[0]:
        # 市盈率分布
        fig = px.bar(
            data, 
            x="代码", 
            y="市盈率", 
            color="涨跌幅",
            hover_data=["名称", "最新价", "市净率", "总市值(亿)"],
            title="价值股市盈率分布",
            color_continuous_scale="RdYlGn_r"
        )
        st.plotly_chart(fig, use_container_width=True)
    
    with viz_tabs[1]:
        # 市净率分布
        fig = px.bar(
            data, 
            x="代码", 
            y="市净率", 
            color="涨跌幅",
            hover_data=["名称", "最新价", "市盈率", "总市值(亿)"],
            title="价值股市净率分布",
            color_continuous_scale="RdYlGn_r"
        )
        st.plotly_chart(fig, use_container_width=True)
    
    with viz_tabs[2]:
        # 市值分布
        fig = px.scatter(
            data, 
            x="市盈率", 
            y="市净率", 
            size="总市值(亿)", 
            color="涨跌幅",
            hover_data=["代码", "名称", "最新价"],
            title="价值股市值分布",
            color_continuous_scale="RdYlGn_r"
        )
        st.plotly_chart(fig, use_container_width=True)
    
    with viz_tabs[3]:
        # 跌幅分布
        fig = px.histogram(
            data, 
            x="涨跌幅", 
            nbins=20,
            title="价值股跌幅分布"
        )
        st.plotly_chart(fig, use_container_width=True)

def create_price_drop_visualizations(data):
    """创建大跌股票数据可视化图表"""
    if data.empty:
        return
    
    st.subheader("数据可视化")
    
    # 创建跌幅与成交量关系图
    fig = px.scatter(
        data,
        x="涨跌幅",
        y="成交量比",
        size="总市值(亿)",
        color="信号类型",
        hover_data=["代码", "名称", "最新价", "市盈率", "市净率"],
        title="大跌股票跌幅与成交量关系"
    )
    st.plotly_chart(fig, use_container_width=True)
    
    # 创建信号类型分布饼图
    if "信号类型" in data.columns:
        signal_counts = data["信号类型"].value_counts().reset_index()
        signal_counts.columns = ["信号类型", "数量"]
        
        fig = px.pie(
            signal_counts,
            values="数量",
            names="信号类型",
            title="买入信号类型分布"
        )
        st.plotly_chart(fig, use_container_width=True)

def show_investment_advice(data, drop_max):
    """显示投资建议"""
    if data.empty:
        return
    
    st.subheader("投资建议")
    
    # 选择前5只最具投资价值的股票
    top_stocks = data.sort_values(by=["市盈率", "市净率"]).head(5)
    
    for _, stock in top_stocks.iterrows():
        # 计算格雷厄姆数值
        graham_value = stock["市盈率"] * stock["市净率"]
        
        # 计算建议买入价格（当前价格的95%）
        suggested_buy_price = stock["最新价"] * 0.95
        
        # 计算止损价格（当前价格的92%）
        stop_loss_price = stock["最新价"] * 0.92
        
        # 计算止盈价格（当前价格的115%）
        take_profit_price = stock["最新价"] * 1.15
        
        # 显示建议
        st.markdown(f"""#### {stock['代码']} - {stock['名称']}  
        **当前价格**: {stock['最新价']:.2f} | **涨跌幅**: {stock['涨跌幅']:.2f}%  
        **市盈率**: {stock['市盈率']:.2f} | **市净率**: {stock['市净率']:.2f} | **格雷厄姆数值**: {graham_value:.2f}  
        **总市值**: {stock['总市值(亿)']:.2f}亿元  
        
        **投资建议**:  
        - 建议买入价格: {suggested_buy_price:.2f}  
        - 止损价格: {stop_loss_price:.2f}  
        - 止盈价格: {take_profit_price:.2f}  
        - 投资理由: 该股符合格雷厄姆价值投资标准，市盈率和市净率较低，且最近有{abs(stock['涨跌幅']):.2f}%的回调，提供了较好的低吸机会。  
        """)
        
        st.markdown("---")

if __name__ == "__main__":
    main()